module smooth_16 (
    input           clk,
    input           rst,
    input           strb,
    input  [15:0]   in_re,
    input  [15:0]   in_im,
    output [32:0]   out_smooth,
    output [32:0]   out_ori,
    output          strb_o,
    output          strb_o_16
);
    parameter       size        = 16;
    parameter       width       = 32; //I:16_15 Q:16_15

    //CNT
    reg  [5:0]      cnt;
    always @(posedge clk ) begin
        if (rst) cnt <= 'b0;
        else if (strb) cnt <= (cnt >= 5'd15) ? 'b0  : cnt +1'b1;
    end

    //SHIFTREG
    reg  [width-1:0]    smt_reg [0:size-1];
    assign              out_ori     =      smt_reg [size-1];
    integer             i;

    always @(posedge clk ) begin
        if (rst) begin
            for (i = 0; i < size ; i = i + 1) 
            begin
                smt_reg [i]         <=      'b0;
            end
        end
        else if (strb) begin
            smt_reg [0]             <=      {in_re,in_im};
            for (i = 1; i < size; i = i+1) 
            begin
                smt_reg [size - i]  <=       smt_reg [size - i -1];
            end
        end
        
    end

    //ACC
    reg [width + 4 + 4-1 :0]            acc;
    assign  out_smooth =  {acc[width+4+4-1: width+4+4-16], acc [width/2 + 4 -1 : 4 ]};

    always @(posedge clk ) begin
        if(rst) acc <= 'b0;
        else if(strb) begin
            acc[width+4+4-1 : (width+4+4)/2 ]       <=          acc[width+4+4-1 : (width+4+4)/2 ] + { { 4{in_re[15]} } ,in_re} + ~ { { 4{smt_reg[size-1][width-1]} }   ,smt_reg[size-1][width-1:width/2]} +1'b1 ;
            acc[width/2+4-1 : 0]                    <=          acc[width/2+4-1 : 0]              + { { 4{in_im[15]} } ,in_im} + ~ { { 4{smt_reg[size-1][width/2-1]} } ,smt_reg[size-1][width/2-1:0]}     +1'b1 ;
        end
    end

    //strb_o_16
    reg             strb_o_16_r;
    assign          strb_o_16       =       strb_o_16_r;
    
    always @(posedge clk) begin
        if (rst)    strb_o_16_r     <=      1'b1;
        else        strb_o_16_r     <=      (cnt == 5'd15)? 1'b1 : 1'b0;
    end

    //strb_o
    reg             strb_o_r;
    assign          strb_o           =      strb_o_r;

    always @(posedge clk) begin
        if (rst)    strb_o_r         <=     1'b1;
        else        strb_o_r         <=     strb;
    end
    

endmodule